/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 * Description: Pangea RDMA Driver Vendor Hooks
 */

#ifdef CONFIG_VENDOR_PANGEA_RDMA_HOOKS
#undef TRACE_SYSTEM
#define TRACE_SYSTEM rdma_pangea

#define TRACE_INCLUDE_PATH trace/hooks
#if !defined(RDMA_PANGEA_HOOK_H) || defined(TRACE_HEADER_MULTI_READ)
#define RDMA_PANGEA_HOOK_H
#include <linux/tracepoint.h>
#include <trace/hooks/vendor_hooks.h>
#include <linux/kernel.h>
#include <rdma/ib_verbs.h>
#include <linux/jiffies.h>

#define PANGEA_ERR 2
#define PANGEA_WARN 3
#define PANGEA_INFO 4
#define PANGEA_DEBUG 5

DECLARE_HOOK(ofed_log_print_hook,
	TP_PROTO(int level, const char *msg, const char *func_name, int code_line),
	TP_ARGS(level, msg, func_name, code_line));

DECLARE_HOOK(ofed_log_print_limit_hook,
	TP_PROTO(int level, const char *msg, const char *func_name, int code_line),
	TP_ARGS(level, msg, func_name, code_line));

DECLARE_HOOK(ofed_monitor_exec_time_start,
	TP_PROTO(struct timespec64 *start),
	TP_ARGS(start));

DECLARE_HOOK(ofed_monitor_exec_time_end,
	TP_PROTO(struct timespec64 *start,
			struct ib_device *ibdev, const char *op_str),
	TP_ARGS(start, ibdev, op_str));

#ifdef CONFIG_CENTRALIZED_STORAGE
DECLARE_HOOK(ib_pangea_exec_get_dev_slot_id,
	TP_PROTO(struct ib_device *device, unsigned int *slot_id, int *ret),
	TP_ARGS(device, slot_id, ret));

DECLARE_HOOK(ib_pangea_exec_get_board_slot,
	TP_PROTO(unsigned int *slot, int *ret),
	TP_ARGS(slot, ret));

DECLARE_HOOK(ib_exec_umem_is_umm_addr,
	TP_PROTO(unsigned long addr, bool *flag),
	TP_ARGS(addr, flag));

DECLARE_HOOK(ib_exec_umm_get_pyhs_addr,
	TP_PROTO(unsigned long addr, phys_addr_t *phy_addr),
	TP_ARGS(addr, phy_addr));

DECLARE_HOOK(ib_device_exec_cmdq_timeout,
	TP_PROTO(struct ib_device *device),
	TP_ARGS(device));
#endif

#define MAX_RDMA_LOG_LENGTH 511

#define ofed_log_print(level, msg, ...) \
do { \
	char buf[MAX_RDMA_LOG_LENGTH] = { 0 }; \
											\
	snprintf(buf, (uint64_t)MAX_RDMA_LOG_LENGTH - 1, msg, ##__VA_ARGS__); \
	buf[MAX_RDMA_LOG_LENGTH - 1] = '\0'; \
	trace_ofed_log_print_hook(level, (const char *)&buf, __func__, __LINE__); \
} while (0)

#define ofed_log_print_limit(level, msg, ...) \
do { \
	char buf[MAX_RDMA_LOG_LENGTH] = { 0 }; \
			\
	snprintf(buf, (uint64_t)MAX_RDMA_LOG_LENGTH - 1, msg, ##__VA_ARGS__); \
	buf[MAX_RDMA_LOG_LENGTH - 1] = '\0'; \
	trace_ofed_log_print_limit_hook(level, (const char *)&buf, __func__, __LINE__); \
} while (0)

#ifdef CONFIG_CENTRALIZED_STORAGE
int ib_pangea_get_dev_slot_id(struct ib_device *device, unsigned int *slot_id);

int ib_pangea_get_board_slot(unsigned int *slot);
#endif

#if defined(CONFIG_CENTRALIZED_STORAGE) || defined(CONFIG_DISTRIBUTED_STORAGE)
bool ib_umem_is_umm_addr(unsigned long addr);

phys_addr_t ib_umm_get_pyhs_addr(unsigned long addr);
#endif
#endif /* if !defined(RDMA_PANGEA_HOOK_H) || defined(TRACE_HEADER_MULTI_READ) */

 /* This part must be outside protection */
#include <trace/define_trace.h>

#else
#ifndef RDMA_PANGEA_HOOK_H
#define RDMA_PANGEA_HOOK_H

#define PANGEA_ERR 2
#define PANGEA_WARN 3
#define PANGEA_INFO 4
#define PANGEA_DEBUG 5

#define trace_ofed_monitor_exec_time_start(start)
#define trace_ofed_monitor_exec_time_end(start, ibdev, op_str)

static inline void ofed_log_print(int level, const char *msg, ...)
{
}

static inline void ofed_log_print_limit(int level, const char *msg, ...)
{
}

#ifdef CONFIG_CENTRALIZED_STORAGE
static inline int ib_pangea_get_dev_slot_id(struct ib_device *device, unsigned int *slot_id)
{
	return 0;
}

static inline int ib_pangea_get_board_slot(unsigned int *slot)
{
	return 0;
}
#endif

#if defined(CONFIG_CENTRALIZED_STORAGE) || defined(CONFIG_DISTRIBUTED_STORAGE)
static inline bool ib_umem_is_umm_addr(unsigned long addr)
{
	return false;
}

static inline phys_addr_t ib_umm_get_pyhs_addr(unsigned long addr)
{
	return 0;
}
#endif
#endif /* ifndef RDMA_PANGEA_HOOK_H */
#endif /* ifdef CONFIG_VENDOR_PANGEA_RDMA_HOOKS */

